#import "CameraProductPlugin.h"

#import <BluetoothConfiger/BluetoothConfiger.h>
#import <BaseCamera/BaseCamera.h>
#import <WDLogger/WDLogger.h>


@interface CameraProductPlugin ()<BluetoothDeviceConfigerDelegate, CameraDelegate>

@property (nonatomic, strong) FlutterEventSink eventSink;

@property (nonatomic, assign) BOOL isInitialized;

@end

@implementation CameraProductPlugin

+ (instancetype)sharedInstance {
    static CameraProductPlugin *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

// 防止通过其他方式创建实例
- (instancetype)init {
    self = [super init];
    if (self) {
        // 初始化代码
    }
    return self;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static CameraProductPlugin *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return self;
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"camera_product_plugin"
            binaryMessenger:[registrar messenger]];
  CameraProductPlugin* instance = [CameraProductPlugin sharedInstance];
  [registrar addMethodCallDelegate:instance channel:channel];
    
    FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"camera_product_plugin_event" binaryMessenger:[registrar messenger]];
    [eventChannel setStreamHandler:instance];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  } else if ([@"initCameraSDK" isEqualToString:call.method]) {
      [self c_initSDK];
  } else if ([@"scanBluetooth" isEqualToString:call.method]) {
      [self scanBluetooth];
  } else if ([@"connectBluetooth" isEqualToString:call.method]) {
      NSDictionary *arguments = call.arguments;
      NSLog(@"iOS插件 开始链接蓝牙");
      NSLog([self jsonStringOfDic:arguments]);
      if (![arguments isKindOfClass:[NSDictionary class]]) {
          return;
      }
      
      if (arguments[@"param"] == NULL  ) {
          return;
      }
      
      NSDictionary *bluetoothInfo = [self jsonStringToDictionary:arguments[@"param"]];
      if (bluetoothInfo != NULL) {
          BluetoothInfo *bluInfo = [[BluetoothInfo alloc] init];
          bluInfo.name = bluetoothInfo[@"mBleName"];
          bluInfo.connected = [bluetoothInfo[@"connected"] boolValue];
          [self connectToBluetooth:bluInfo];
      }
      
  } else if ([@"scanWIFI" isEqualToString:call.method]) {
      [self scanWifi];
  } else if ([@"connectWIFI" isEqualToString:call.method]) {
      NSDictionary *arguments = call.arguments;
      NSLog(@"iOS插件 开始连接wifi");
      NSLog([self jsonStringOfDic:arguments]);
      if (![arguments isKindOfClass:[NSDictionary class]]) {
          return;
      }
      
      if (arguments[@"param"] == NULL  ) {
          return;
      }
      
      NSDictionary *wifiInfoDic = [self jsonStringToDictionary:arguments[@"param"]];
      if (wifiInfoDic != NULL) {
          WifiInfo *wInfo = [[WifiInfo alloc] init];
          wInfo.wifiSSID = wifiInfoDic[@"ssid"];
          wInfo.userInputPassword = wifiInfoDic[@"password"];
          [self connectToWifi:wInfo];
      } else {
          NSLog(@"wifi 参数错误");
      }
  } else if ([@"takePhoto" isEqualToString:call.method]) {
      [self clickTakePhoto];
  } else if ([@"removeCameraListener" isEqualToString:call.method]) {
      [CameraShareManager removeObserver:self];
      BTDeviceConfiger.delegate = NULL;
  } else if ([@"disConnectBluetooth" isEqualToString:call.method]) {
      [self closeConnectBT];
  }  else if ([@"getCurrentDeviceName" isEqualToString:call.method]) {
      // 获取当前已链接设备的名字
      [self receiveCommendToGetCurrentDevice];
  }  else if ([@"getCurrentDeviceWifiSSID" isEqualToString:call.method]) {
      // 获取当前已链接设备的wifi名字
      [self receiveCommendToGetCurrentWifiSSID];
  }  else if ([@"getCurrentDeviceWifiSatate" isEqualToString:call.method]) {
      // 获取当前已链接设备的wifi状态
      [self receiveCommendToGetCurrentWifiState];
  }  else {
    result(FlutterMethodNotImplemented);
  }
}

#pragma mark - FlutterStreamHandler 协议 - EventSink 相关
- (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments {
    _eventSink = NULL;
    return NULL;
}

- (FlutterError * _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(nonnull FlutterEventSink)events {
    NSLog(@"Event channel listened with arguments: %@", arguments);
    _eventSink = events;
    return NULL;
}


- (void)c_initSDK {
    NSLog(@"插件iOS--初始化SDK");
    CMConfigureShareHandle.bluetoothAssistance = YES;

    if (!_isInitialized) {
        [CameraShareManager startInitialize];
    }
    [CameraShareManager addObserver:self];
    BTDeviceConfiger.delegate = self;
    _isInitialized = YES;
    
}

- (void)bluetoothDisconnect { 
    // 蓝牙断开连接
}

- (void)bluetoothPowerOff { 
    // 蓝牙关闭
}


#pragma mark - 处理flutter指令
// 扫描蓝牙
- (void)scanBluetooth{
    NSLog(@"插件iOS-扫描蓝牙");
    [BTDeviceConfiger scanBluetoothWithKeyword:@"IPC" deviceListCallback:^(NSArray * _Nonnull list) {
        if (list.count > 0){
            BluetoothInfo* blueInfo = list.lastObject;
            NSDictionary *dic = @{@"mBleName":blueInfo.name,@"connected":[NSNumber numberWithBool:blueInfo.connected],@"mBleAddress":@"--:--:--:--"};
            NSString *jsonStr = [self jsonStringOfDic:dic];
            NSDictionary *resultInfoDic = @{@"find_new_device":jsonStr};
            // 停止扫描
            [BTDeviceConfiger stopScanBluetooth];
            // 确保在主线程发送事件
            dispatch_async(dispatch_get_main_queue(), ^{
                if (self.eventSink) {
                    NSLog(@"插件iOS:扫描蓝牙设备 开始回调了");
                    self.eventSink(resultInfoDic);
                }
            });
        }
    }];
}

// 连接蓝牙
- (void)connectToBluetooth:(BluetoothInfo*)bt{
    NSLog([NSString stringWithFormat:@"插件iOS:要连接的设备 %@ 连接状态：%d",bt.name, bt.connected]);
    BluetoothInfo *targetBt = NULL;
    NSLog([NSString stringWithFormat:@"插件iOS:BTDeviceConfiger.devices：%d",BTDeviceConfiger.devices.count]);
    for (BluetoothInfo *aBt in BTDeviceConfiger.devices) {
        if ([aBt.name isEqual:bt.name]) {
            targetBt = aBt;
            break;
        }
    }
    if (targetBt == NULL) {return;}
    if (targetBt.connected == 1) {
        // 已连接
        NSLog(@"插件iOS: 连接蓝牙 State:已连接");
        self.eventSink(@{@"connect_device_code":@"200"});
    } else {
        [BTDeviceConfiger connectBluetoothWithDevice:targetBt Completion:^(BOOL connectResult, NSError * _Nullable error) {
            NSLog(@"插件iOS: 连接蓝牙 State:%d, error:%@", connectResult, error);
            if (connectResult == YES) {
                self.eventSink(@{@"connect_device_code":@"200"});
            } else {
                self.eventSink(@{@"connect_device_code":@"300"});
            }
        }];
    }
    
}
// 扫描wifi
- (void)scanWifi{
    
    [BTDeviceConfiger scanApListWithCompletion:^(NSArray<WifiInfo *> * _Nonnull wifiInfos, NSError * _Nullable error) {
        NSLog(@"wifi: %@", wifiInfos);
    }];
}

// 连接wifi
- (void)connectToWifi:(WifiInfo *)wifi {
//    WifiInfo *nWifi = [[WifiInfo alloc] init];
//    nWifi.wifiSSID = @"Lanjing2.4";
//    nWifi.userInputPassword = @"Lanjing@1209";
    NSLog([NSString stringWithFormat:@"要连接的wifi:%@  密码:%@",wifi.wifiSSID,wifi.userInputPassword]);
    [BTDeviceConfiger connectWifi:wifi Completion:^(WifiInfo * _Nonnull wifiInfo, int errorCode, int wifiState) {
        NSLog(@"连接WiFi ssid:%@, err:%d, state:%d", wifiInfo.wifiSSID, errorCode, wifiState);
        self.eventSink(@{@"connect_wifi_code":@"200"});
    }];
}


// 点击拍照
- (void)clickTakePhoto{
    NSDictionary *p = @{@"code":@"200",@"photo_path":@""};
    NSString *pStr = [self jsonStringOfDic:p];
    _eventSink(@{@"take_photo_code":pStr});
}


// 断开蓝牙
- (void)closeConnectBT{
    BluetoothInfo *bt = BTDeviceConfiger.self.connectedDevice;
    if (bt != NULL) {
        [BTDeviceConfiger disConnectBlueDeviceWithCompletion:^(NSError * _Nullable error) {
            
        } device:bt];
    }
}

#pragma mark - CameraDelegate
- (void)deviceConnectWithStatus:(CMConnectStatus)status param:(NSDictionary *)param
{
    switch (status) {
            
        case CMConnectConnecting:
            NSLog(@"CMConnect Connecting");
            _eventSink(@{@"wifi_camera_state":@"connecting"});
            break;
        case CMConnectConnected: {
            NSLog(@"CMConnect Connected");
            _eventSink(@{@"wifi_camera_state":@"online"});
            break;
        }
        case CMConnectDisconnected: {
            NSLog(@"CMConnect Disconnected");
            _eventSink(@{@"wifi_camera_state":@"offline"});

            break;
        }
        case CMConnectError: {
            NSLog(@"Failed to recognize: %@", param);
            _eventSink(@{@"wifi_camera_state":@"connect_error"});

            break;
        }
        default:
            break;
    }
}


//获取当前设备所连接wifi的ssid
- (void)receiveCommendToGetCurrentWifiSSID {
    NSLog(@"收到按键指令-获取SSID");
    __weak typeof(self) weakSelf = self;

    [BTDeviceConfiger acceptDeviceSSIDWithCompletion:^(NSString * _Nullable ssid, NSError * _Nullable error) {
        NSLog(@"获取到当前设备WIFI的SSID%@",ssid ? ssid : @"unknow");
        weakSelf.eventSink(@{@"current_device_ssid":ssid});
    }];
}

//获取当前设备所连接wifi的状态
- (void)receiveCommendToGetCurrentWifiState {
    __weak typeof(self) weakSelf = self;
    [BTDeviceConfiger acceptWifiStatusWithCompletion:^(int wifiState, NSError * _Nullable error) {
        NSString *stateStr = [NSString stringWithFormat:@"%d",wifiState];
        weakSelf.eventSink(@{@"current_device_wifi_state":stateStr});
    }];
}

//获取当前所连接设备
- (void)receiveCommendToGetCurrentDevice {
    NSString *currentDeviceName = BTDeviceConfiger.connectedDevice.name ? BTDeviceConfiger.connectedDevice.name : @"";
    self.eventSink(@{@"current_device":currentDeviceName});
}


// 收到了点击按钮拍照
- (void)receiveCommandTakePhoto {
    NSLog(@"收到按键指令-拍照");
    [self clickTakePhoto];
}

/// 收到按键指令-录制
- (void)receiveCommandStartRecord {
    NSLog(@"收到按键指令-录制");
}

/// 收到按键指令-停止录制 / 在进入后台或掉线情况下,也会调用.
- (void)receiveCommandStopRecord {
    NSLog(@"收到按键指令-停止录制");
}

- (void)receiveData:(NSData *)data image:(UIImage *)image {
    if (data != NULL) {
        _eventSink(@{@"bitmap_steam":data});
    }
}

- (void)receiveOriginImage:(UIImage *)originImage processedImage:(UIImage *)processedImage
{
    // 画面回调
}

- (NSString *)jsonStringOfDic:(NSDictionary *)dictionary{
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
     
    if (!jsonData) {
        NSLog(@"Got an error: %@", error);
        return @"";
    } else {
        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        NSLog(@"JSON String: %@", jsonString);
        return jsonString;
    }
}

- (NSDictionary *)jsonStringToDictionary:(NSString *)jsonString {
    NSError *error = nil;
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
     
    if (error) {
        NSLog(@"JSON解析错误: %@", error);
        return NULL;
    } else {
        // 使用jsonDict
        return  jsonDict;
    }
}

@end



